package uy.com.tsi2G7.superbet.integration.betfair.global.service;

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.Toolkit;
import java.rmi.RemoteException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;

import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTable;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.TableModel;

import org.apache.commons.lang.StringUtils;

import uy.com.tsi2G7.superbet.integration.betfair.exchange.GetAllMarketsReq;
import uy.com.tsi2G7.superbet.integration.betfair.exchange.GetAllMarketsResp;
import uy.com.tsi2G7.superbet.integration.betfair.exchange.GetMarketPricesReq;
import uy.com.tsi2G7.superbet.integration.betfair.exchange.GetMarketPricesResp;
import uy.com.tsi2G7.superbet.integration.betfair.exchange.GetMarketProfitAndLossReq;
import uy.com.tsi2G7.superbet.integration.betfair.exchange.GetMarketProfitAndLossResp;
import uy.com.tsi2G7.superbet.integration.betfair.exchange.GetMarketReq;
import uy.com.tsi2G7.superbet.integration.betfair.exchange.GetMarketResp;
import uy.com.tsi2G7.superbet.integration.betfair.exchange.MarketPrices;
import uy.com.tsi2G7.superbet.integration.betfair.exchange.ProfitAndLoss;
import uy.com.tsi2G7.superbet.integration.betfair.exchange.Runner;
import uy.com.tsi2G7.superbet.integration.betfair.exchange.RunnerPrices;
import uy.com.tsi2G7.superbet.integration.betfair.exchange.service.BFExchangeServiceProxy;
import uy.com.tsi2G7.superbet.integration.betfair.global.APIRequestHeader;
import uy.com.tsi2G7.superbet.integration.betfair.global.BFEvent;
import uy.com.tsi2G7.superbet.integration.betfair.global.EventType;
import uy.com.tsi2G7.superbet.integration.betfair.global.GetEventTypesReq;
import uy.com.tsi2G7.superbet.integration.betfair.global.GetEventTypesResp;
import uy.com.tsi2G7.superbet.integration.betfair.global.GetEventsReq;
import uy.com.tsi2G7.superbet.integration.betfair.global.GetEventsResp;
import uy.com.tsi2G7.superbet.integration.betfair.global.LoginReq;
import uy.com.tsi2G7.superbet.integration.betfair.global.LoginResp;
import uy.com.tsi2G7.superbet.integration.betfair.global.LogoutReq;
import uy.com.tsi2G7.superbet.integration.betfair.global.LogoutResp;


public class BFGlobalServiceTest {
	
	private BFGlobalServiceProxy proxy = new BFGlobalServiceProxy();
	private LoginResp loginResponse;
	private APIRequestHeader header;
	private GetEventTypesResp eventTypesResponse;
	private GetEventsResp eventListResponse;
	private AbstractTableModel eventTableModel;
	private BFExchangeServiceProxy exchangeProxy=new BFExchangeServiceProxy();
	private uy.com.tsi2G7.superbet.integration.betfair.exchange.APIRequestHeader exchangeHeader=new uy.com.tsi2G7.superbet.integration.betfair.exchange.APIRequestHeader();
	private int currentEventRow=-1;
	private int currentEventTypeRow=-1;
	private int currentMarketRow=-1;
	private String[] market;
	private AbstractTableModel marketTableModel;
	private JTable eventTable;
	private AbstractTableModel mTableModel;
	private GetAllMarketsResp allMarketResponse;
	private GetMarketPricesResp getMarketPricesResp;
	private GetMarketResp marketResponse;
	private GetMarketProfitAndLossResp marketProfitAndLossReq;
	
	private void login() {
		try {
			LoginReq loginRequest=new LoginReq("0",0,"rafaeltsi2",82,"rscara",0);
			loginResponse = proxy.login(loginRequest);
			System.out.println("Login "+loginResponse.getHeader().getErrorCode());
			header=new APIRequestHeader();
			header.setClientStamp(0);
			header.setSessionToken(loginResponse.getHeader().getSessionToken());
			exchangeHeader.setClientStamp(0);
			exchangeHeader.setSessionToken(loginResponse.getHeader().getSessionToken());
		} catch (RemoteException e1) {
			e1.printStackTrace();
			logout();
		}
	}
	
	private void getEvents(int eventId) {
		try {
			GetEventsReq eventsRequest=new GetEventsReq();
			eventsRequest.setHeader(header);
			eventsRequest.setEventParentId(eventId);
			eventListResponse = proxy.getEvents(eventsRequest);
			for (BFEvent bfevent : eventListResponse.getEventItems()) {
				System.out.println(bfevent.getEventName()+" "+bfevent.getEventId()+" "+bfevent.getEventTypeId()+" "+bfevent.getMenuLevel());
			}
		} catch (RemoteException e) {
			e.printStackTrace();
			logout();
		}
	}
	
	private void getAllMarkets(int[] eventTypeIds) {
		try {
			GetAllMarketsReq getAllMarketsReq=new GetAllMarketsReq(exchangeHeader,null,eventTypeIds,null, null,null);
			 allMarketResponse = exchangeProxy.getAllMarkets(getAllMarketsReq);
			System.out.println("getAllMarkets "+allMarketResponse.getErrorCode());
			market = StringUtils.split(allMarketResponse.getMarketData(), ":");
		} catch (RemoteException e) {
			e.printStackTrace();
			logout();
		}

	}
	
	
	private void getEventTypes() {
		try {
			GetEventTypesReq request=new GetEventTypesReq();
			request.setHeader(header);
			eventTypesResponse = proxy.getActiveEventTypes(request);
			System.out.println("getActiveEventTypes = "+eventTypesResponse.getErrorCode());
			int[] ids = new int[eventTypesResponse.getEventTypeItems().length];
			int index=0;
			for (EventType event : eventTypesResponse.getEventTypeItems()) {
				ids[index++]=event.getId();
			}
			getAllMarkets(ids);			
		} catch (RemoteException e) {
			e.printStackTrace();
			logout();
		}
	}
	
	
	
	
	private void logout() {
		try {
			LogoutReq logoutRequest=new LogoutReq(header);
			LogoutResp logoutResponse = proxy.logout(logoutRequest);
			System.out.println("logout = "+logoutResponse.getErrorCode());
		} catch (RemoteException e) {
			e.printStackTrace();
		}
	}


	public static void main(String[] args) {
		BFGlobalServiceTest main = new BFGlobalServiceTest();
		main.login();
		main.getEventTypes();
		JFrame frame = new JFrame();
		
		Toolkit tk = Toolkit.getDefaultToolkit();//see Cay Horstman, p. 273 , Core Java I
		Dimension d = tk.getScreenSize(); //Gets the user screen size
		int scrnHigh = d.height; //Pulls out the High
		int scrnWide = d.width; //Pulls out the Wide 
		//setSize(scrnWide *9/10, scrnHigh *9/10);//sets screen to 0.9 size
		frame.setSize(scrnWide, scrnHigh);//sets screen to FULL size
		//setLocation(scrnWide *1/20, scrnHigh *1/20);//CENTER it for 9/10th size
		frame.setLocation(0, 0);//
		frame .setContentPane(main.createmainPane());
		frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
		frame.setVisible(true);
	}

	private  JPanel createmainPane() {
		JPanel panel=new JPanel();
		panel.setLayout(new BorderLayout()); 
		panel.add(createOptionTable(),BorderLayout.WEST);
		panel.add(createButtonPanel(),BorderLayout.SOUTH);
		panel.add(createEventPanel(),BorderLayout.EAST);
		return panel;
	}

	private Component createEventPanel() {
		JSplitPane panel = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,
				createCenterTable(), createMarketTable());
		JSplitPane mainPanel = new JSplitPane(JSplitPane.VERTICAL_SPLIT,
				panel, createMarketPanel());
		return mainPanel;
	}

	private Component createButtonPanel() {
		JPanel panel = new JPanel(new GridLayout(3,3));
		return panel;
	}

	private void getMarket(int currentMarketRow) {
		try {
			GetMarketPricesReq getMarketPricesReq = new GetMarketPricesReq(exchangeHeader, null, Integer.valueOf(getCurrentMarkets().get(currentMarketRow)[0]));
			getMarketPricesResp = exchangeProxy.getMarketPrices(getMarketPricesReq);
			System.out.println("GetMarketPricesReq "+getMarketPricesResp.getErrorCode());
			
			GetMarketReq marketReq = new GetMarketReq(exchangeHeader,null, Integer.valueOf(getCurrentMarkets().get(currentMarketRow)[0]), false);
			//GetAllMarketsReq getAllMarketsReq=new GetAllMarketsReq(exchangeHeader,null,eventTypeIds,null, null,null);
			marketResponse = exchangeProxy.getMarket(marketReq);
			System.out.println("getMarket "+marketResponse.getErrorCode());
			
			GetMarketProfitAndLossReq marketProfitAndLoss=new GetMarketProfitAndLossReq();
			marketProfitAndLoss.setHeader(exchangeHeader);
			marketProfitAndLoss.setMarketID(Integer.valueOf(getCurrentMarkets().get(currentMarketRow)[0]));
			marketProfitAndLossReq =exchangeProxy.getMarketProfitAndLoss(marketProfitAndLoss);
			
			
			
		} catch (RemoteException e) {
			e.printStackTrace();
			logout();
		}
	}
	
	
	private List<String[]> getCurrentMarkets(){
		List<String[]> res = new ArrayList<String[]>();
		if(currentEventTypeRow>0&&currentEventRow>0)
			for (String text : market) {
				String[] fields = StringUtils.split(text,"~");
				if(fields.length>=12){
					if(fields[5].indexOf(
							String.valueOf(
									eventListResponse.getEventItems()[currentEventRow].getEventName()))>0&&
									fields[5].indexOf(
											String.valueOf(
													eventTypesResponse.getEventTypeItems()[currentEventTypeRow].getName()))>0&&
													Integer.valueOf(fields[12])==1)
						res.add(fields);
				}
					
			}
		return res;
	}
	
	private  JComponent createMarketPanel() {
		final JTable table=new JTable();
		mTableModel = new AbstractTableModel() {
			@Override
			public Object getValueAt(int rowIndex, int columnIndex) {
				if(getMarketPricesResp==null)
						return null;
				MarketPrices prices = getMarketPricesResp.getMarketPrices();
				Runner[] runners = marketResponse.getMarket().getRunners();
				String res = "";
	 			res+=runners[rowIndex].getName()+" ";
				for (RunnerPrices price : prices.getRunnerPrices()) {
					if(price.getSelectionId()==runners[rowIndex].getSelectionId()&&price.getBestPricesToBack().length>0)
						res+=price.getBestPricesToBack()[price.getBestPricesToBack().length-1].getPrice();
				}
				
				for (ProfitAndLoss profitAndLosses : marketProfitAndLossReq.getAnnotations()) {
					if(profitAndLosses.getSelectionId()==runners[rowIndex].getSelectionId())
						res+=" "+profitAndLosses.getFutureIfWin()+" "+profitAndLosses.getIfWin();
				}
				
				
				return res;
			}
			
			@Override
			public int getRowCount() {
				return marketResponse==null?0:marketResponse.getMarket().getRunners().length;
			}
			
			@Override
			public int getColumnCount() {
				return 1;
			}
		};
		/*table.getSelectionModel().addListSelectionListener(
		        new ListSelectionListener() {
					public void valueChanged(ListSelectionEvent event) {
		                int viewRow = table.getSelectedRow();
		                if (viewRow < 0) {
		                } else {
		                    int modelRow = 
		                        table.convertRowIndexToModel(viewRow);
		                    
		                }
		            }
		        }
		);*/
		table.setModel(mTableModel);
		return new JScrollPane(table);
	}
	
	private  JComponent createMarketTable() {
		final JTable table=new JTable();
		marketTableModel=new AbstractTableModel() {
			@Override
			public Object getValueAt(int rowIndex, int columnIndex) {
				List<String[]> markets = getCurrentMarkets();
				String[] fields =markets.get(rowIndex);
					return /*" Name="+fields[1]+"Menu "+*/fields[5].substring(fields[5].lastIndexOf("\\")+1)+" "+fields[1]+" "+new SimpleDateFormat("dd/MM/yyyy HH:mm:ss").format(new java.util.Date(Long.valueOf(fields[4])));
				
			}
			
			@Override
			public int getRowCount() {
				return getCurrentMarkets().size();
			}
			
			@Override
			public int getColumnCount() {
				return 1;
			}
		};
		table.getSelectionModel().addListSelectionListener(
		        new ListSelectionListener() {
					public void valueChanged(ListSelectionEvent event) {
		                int viewRow = table.getSelectedRow();
		                if (viewRow < 0) {
		                } else {
		                    int modelRow = 
		                        table.convertRowIndexToModel(viewRow);
		                    if(modelRow!=currentMarketRow){
		                    	currentMarketRow=modelRow;
		                    	getMarket(currentMarketRow);
		                    }
		                    mTableModel.fireTableDataChanged();
		                }
		            }
		        }
		);
		table.setModel(marketTableModel);
		return new JScrollPane(table);
	}

	private  JComponent createCenterTable() {
		eventTable=new JTable();
		eventTableModel=new AbstractTableModel() {
			@Override
			public Object getValueAt(int rowIndex, int columnIndex) {
				return eventListResponse==null?null:eventListResponse.getEventItems()[rowIndex].getEventName();
			}
			
			@Override
			public int getRowCount() {
				return eventListResponse==null?0:eventListResponse.getEventItems().length;
			}
			
			@Override
			public int getColumnCount() {
				return 1;
			}
		};
		eventTable.getSelectionModel().addListSelectionListener(
		        new ListSelectionListener() {
					public void valueChanged(ListSelectionEvent event) {
		                int viewRow = eventTable.getSelectedRow();
		                if (viewRow < 0) {
		                } else {
		                    int modelRow = 
		                    		eventTable.convertRowIndexToModel(viewRow);
		                    if(modelRow!=currentEventRow){
		                    	currentEventRow=modelRow;
		                    }
		                    marketTableModel.fireTableDataChanged();
		                }
		            }
		        }
		);
		eventTable.setModel(eventTableModel);
		return new JScrollPane(eventTable);
	}
	
	private  JComponent createOptionTable() {
		final JTable table=new JTable();
		TableModel dataModel=new AbstractTableModel() {
			@Override
			public Object getValueAt(int rowIndex, int columnIndex) {
				return eventTypesResponse.getEventTypeItems()[rowIndex].getName();
			}
			
			@Override
			public int getRowCount() {
				return eventTypesResponse.getEventTypeItems().length;
			}
			
			@Override
			public int getColumnCount() {
				return 1;
			}
		};
		table.getSelectionModel().addListSelectionListener(
		        new ListSelectionListener() {
					public void valueChanged(ListSelectionEvent event) {
		                int viewRow = table.getSelectedRow();
		                if (viewRow < 0) {
		                	eventListResponse=null;
		                } else {
		                    int modelRow = 
		                        table.convertRowIndexToModel(viewRow);
		                    if(modelRow!=currentEventTypeRow){
		                    	getEvents(eventTypesResponse.getEventTypeItems()[modelRow].getId());
		                    	currentEventTypeRow=modelRow;
		                    }
		                }
		                eventTableModel.fireTableDataChanged();
		            }
		        }
		);
		table.setModel(dataModel);
		return new JScrollPane(table);
	}

}
